package com.iqik.change.watch;

import com.iqik.change.source.DataSourceConfig;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class WatchDog implements ApplicationRunner {

    @Autowired
    private DataSourceConfig config;

    private String path = "/dataSource";
    private RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
    private CuratorFramework client;
    private Map<String, String> daraSourceMap = new HashMap<>();

    @Override
    public void run(ApplicationArguments args) throws Exception {
        client = CuratorFrameworkFactory.builder()
                .connectString("132.232.16.135:2181")
                .sessionTimeoutMs(50000)
                .connectionTimeoutMs(30000)
                .retryPolicy(retryPolicy)
                .namespace("base") // 独立的命名空间 在/base目录下
                .build();
        client.start();

        PathChildrenCache pathChildrenCache = new PathChildrenCache(client, path, true);
        pathChildrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE);
        pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
            @Override
            public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent event) throws Exception {
                try {
                    ChildData data = event.getData();
                    switch (event.getType()) {
                        case CHILD_UPDATED:
                            System.out.println(" update node context " + data.getData());
                            setDataSource();
                            break;
                        case CHILD_ADDED:
                            System.out.println(" add node context " + data.getData());
                            break;
                        default:
                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void setDataSource() throws Exception {
        PropertiesConfiguration properties = new PropertiesConfiguration("application.properties");
        properties.setProperty("driverClassName", new String(client.getData().forPath(String.format("%s/%s", path, "driverClassName"))));
        properties.setProperty("password", new String(client.getData().forPath(String.format("%s/%s", path, "password"))));
        properties.setProperty("username", new String(client.getData().forPath(String.format("%s/%s", path, "username"))));
        properties.setProperty("url", new String(client.getData().forPath(String.format("%s/%s", path, "url"))));
        properties.save();
        config.changeDataSource();
    }
}
